<template>
    <div>
        <div id="main" style="width: 100%; height: 92dvh;"></div>

        <el-button class="setParadata" type="primary" style="text-align: center" @click="setParadata">参数设置</el-button>
        <el-button class="seeHistoryBtn" type="primary" style="text-align: center"
            @click="seeHistoryBtn">历史任务</el-button>

        <div v-if=paramMenuBool class="menu">
            <el-card :bordered="true">
                <div slot="header" style="font-weight: bold;margin-bottom:10px;">
                    <span style="font-size:larger;">生成干扰源</span>
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">任务名称:</div>
                    <el-input v-model="menu.taskName" placeholder="请输入任务名称" clearable
                        style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom: 5px; display: flex; align-items: center;">
                    <span style="margin-right: 10px;">区域编号:</span>
                    <el-select v-model="menu.selectSceneNum" style="width:175px" @change="selectScene"
                        placeholder="区域选择">
                        <el-option v-for="num in menu.selectSceneList" :label="num.label"
                            :value="num.value"></el-option>
                    </el-select>
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">经纬范围:</div>
                    <el-input v-model="menu.lonLatRangeStr" placeholder="" clearable :disabled="true"
                        style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">干扰半径:</div>
                    <el-input v-model="menu.interferenceRange" type="number" placeholder="" clearable
                        style="width: 145px; height: 30px;margin-right:5px;" />KM
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">时间起点:</div>
                    <el-input v-model="menu.strartTime" placeholder="" clearable style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">时间终点:</div>
                    <el-input v-model="menu.endTime" placeholder="" clearable style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom:5px;display: flex; align-items: center;">
                    <div>生成方式:</div>
                    <div style="width:10px"></div>
                    <el-radio-group v-model="menu.buildType" size="" @change=changeInterferenceSrcType()>
                        <el-radio-button :label="0">自动生成</el-radio-button>
                        <el-radio-button :label="1">手动生成</el-radio-button>
                    </el-radio-group>
                </div>
                <div v-if="menu.buildType == 1">
                    <div style="margin-bottom:5px; display: flex; align-items: center;">
                        <div style="margin-right:10px; ">干扰数量:</div>
                        <el-input v-model="menu.interferenceNum" type="number" placeholder="" clearable
                            style="width: 175px; height: 30px" />
                    </div>
                </div>
                <div v-if="menu.buildType == 0">
                    <el-input v-model="menu.interferencePosRealText" :disabled=true
                        style="width: 253px; margin-bottom:5px;" :autosize="{ minRows: 3, maxRows: 3 }" type="textarea"
                        placeholder="" />
                </div>
                <div style="text-align: center; float: right; margin-right: 2px; margin-bottom: 5px;">
                    <el-button type="primary" @click="getInterferenceRealPos">生成干扰</el-button>
                </div>
            </el-card>

            <el-card :bordered="true" style="margin-top:1px;">
                <div slot="header" style="font-weight: bold;margin-bottom:10px;">
                    <span style="font-size:larger;">干扰检测和定位</span>
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">网格步长:</div>
                    <el-input v-model="menu.gridSize" type="number" placeholder="" clearable
                        style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">平均误差:</div>
                    <el-input v-model="menu.LocationError_avg" placeholder="" :disabled="true"
                        style="width: 175px; height: 30px" />
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:66px; ">T:</div>
                    <el-input v-model="menu.tData" placeholder="" :disabled="true" style="width: 175px; height: 30px" />
                </div>
                <div style="text-align: center; float: right; margin-right: 2px; margin-bottom: 5px;">
                    <el-button type="primary" @click="startCalculLocatAndDetect">开始计算</el-button>
                </div>
                <!-- <div style="text-align: center; float: right; margin-right: 2px; margin-bottom: 5px;">
                    <el-button type="primary" @click="getPosition">干扰定位</el-button>
                </div>
                <div style="text-align: center; float: right; margin-right: 8px; margin-bottom: 5px;">
                    <el-button type="primary" @click="detectInterference">干扰检测</el-button>
                </div> -->
            </el-card>

            <!-- <el-card :bordered="true" style="margin-top:1px;">
                <div slot="header" style="font-weight: bold;margin-bottom:10px;">
                    <span style="font-size:larger;">数据入库</span>
                </div>
                <div style="margin-bottom:5px; display: flex; align-items: center;">
                    <div style="margin-right:10px; ">任务名称:</div>
                    <el-input v-model="menu.taskName" placeholder="请输入任务名称" clearable
                        style="width: 175px; height: 30px" />
                </div>
                <div style="text-align: center; float: right; margin-right: 2px; margin-bottom: 5px;">
                    <el-button type="primary" @click="pushParamAndResultToSql">数据入库</el-button>
                </div>
            </el-card> -->
        </div>
        
        <div v-if=this.historyMenuBool>
            <div class="history-menu">
                <div style="margin: 1%; display: flex; align-items: center;">
                    <div style="font-size:x-large;">历史任务</div>
                    <div style="font-size:large;margin-right:1%; margin-left:66%;">展示最新</div>
                    <div style="width: 9%; height: 2%" >
                        <el-select v-model="latestDataNum" @change="getLatestData"
                            placeholder="0">
                            <el-option label=5 value=5></el-option>
                            <el-option label=10 value=10></el-option>
                            <el-option label=30 value=30></el-option>
                            <el-option label=50 value=50></el-option>
                        </el-select>
                    </div>
                    <div style="margin-left:1%; font-size:large;">条数据</div>
                </div>
                <el-table :data="historyInfo" border class="history-table">
                    <el-table-column align="center" label="名称" prop="name" fixed width="190"></el-table-column>
                    <el-table-column align="center" label="状态" prop="status" fixed width="100"></el-table-column>
                    <el-table-column align="center" label="时间" prop="createTime" fixed width="160"></el-table-column>
                    <el-table-column align="center" label="区域编号" prop="areaNum" fixed width="100"></el-table-column>
                    <el-table-column align="center" label="干扰半径" prop="paramsData.interferenceRange" fixed
                        width="100"></el-table-column>
                    <el-table-column align="center" label="时间起点" prop="paramsData.strartTime" fixed
                        width="100"></el-table-column>
                    <el-table-column align="center" label="时间终点" prop="paramsData.endTime" fixed
                        width="100"></el-table-column>
                    <el-table-column align="center" label="干扰数量" prop="paramsData.interferenceNum" fixed
                        width="100"></el-table-column>
                    <el-table-column align="center" label="网格大小" prop="gridStep" fixed width="100"></el-table-column>
                    <el-table-column align="center" label="操作" fixed="right" width="105">
                        <template #default="{ row }">
                            <div style="display: flex">
                                <el-button size="small" style="margin-left:0px; background-color:aliceblue"
                                    :disabled="status == '计算完成' ? true : false"
                                    @click="seeOneHistoryInfo(row)">展示成果</el-button>
                                <!-- <el-button size="small" style="background-color:lightcoral"
                                        @click="delOneHistoryInfo(row)">删除 </el-button> -->
                            </div>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </div>

    </div>
</template>

<script>
import * as echarts from 'echarts/core';
import { ElLoading } from 'element-plus';
import { TooltipComponent, VisualMapComponent } from 'echarts/components';
import { CustomChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import 'echarts/extension/bmap/bmap';
import { dataProcess1 } from '@/api/monitor/station'
import { dataProcess2 } from '@/api/monitor/station'
import { queryAdsbLastRecordList } from '@/api/monitor/station'
import { startCalculLocatAndDetectApi } from '@/api/monitor/station'

import { getAdsbLoc } from '@/api/monitor/station'
import { getInterferenceDataList } from '@/api/monitor/station'

export default {
    name: 'BdMap',
    mounted() {
        this.initDisplay()
    },
    data() {
        return {
            // 控制参数表单显示
            paramMenuBool: false,
            historyMenuBool: false,
            chartDom: null,
            myChart: null,
            menu: {
                taskName: '任务一',
                selectSceneNum: null,
                timeStamp: '',
                selectSceneList: [
                    {
                        label: "区域一",
                        value: 1,
                    },
                    {
                        label: "区域二",
                        value: 2,
                    },
                    {
                        label: "区域三",
                        value: 3,
                    }
                ],
                lonLatRangeStr: '',
                minLon: '',
                maxLon: '',
                minLat: '',
                maxLat: '',
                interferenceRange: 50,
                strartTime: "080000",
                endTime: "120000",
                buildType: 1,
                interferenceNum: 3,
                interferencePosReal: [],
                interferencePosRealText: "",
                gridSize: '0.5',
                interferenceMatrixData: [],
                location_detect: [],
                location_real: [],
                LocationError_avg: [],
                tData: null,
                point1: [],
                point2: [],
            },

            // 历史数据
            historyInfo: [],
            latestDataNum: 5,

            // 热力图
            heatMap: {
                lngExtent: '',
                latExtent: '',
                cellCount: '',
                cellSizeCoord: '',
            },

            // 百度地图的标记等设置
            bmapParams: {
                location_real: 'yellow',
                location_detect_virtual: 'green',
                location_detect_true: 'red',
                point1: 'pink',
                point2: 'purple',
                mapModel: '',
                markers: []
            },
        }
    },

    methods: {
        initDisplay() {
            let that = this
            that.chartDom = document.getElementById('main');
            that.myChart = echarts.init(that.chartDom);
            var COLORS = ['#1482e5', '#70b4eb', '#b4e0f3', '#ffffff', '#00ff00', '#ff0000']
            // var COLORS = ['#070093', '#1c3fbf', '#1482e5', '#70b4eb', '#b4e0f3', '#ffffff']
            echarts.use([
                TooltipComponent,
                VisualMapComponent,
                CustomChart,
                CanvasRenderer
            ]);

            var option;

            option = {
                backgroundColor: 'transparent',
                tooltip: {},
                series: [
                    {
                        type: 'custom',
                        coordinateSystem: 'bmap',
                        renderItem: that.renderItem,
                        animation: false,
                        emphasis: {
                            itemStyle: {
                                color: 'yellow'
                            }
                        },
                        encode: {
                            tooltip: 2
                        },
                        data: ''//data
                    }
                ],
                bmap: {
                    center: [116.46, 39.92],
                    zoom: 11.8,
                    roam: true,
                    mapStyle: {
                        styleJson: [
                            { featureType: 'water', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'land', elementType: 'all', stylers: { color: '#f3f3f3' } },
                            { featureType: 'railway', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'highway', elementType: 'all', stylers: { color: '#999999' } },
                            { featureType: 'highway', elementType: 'labels', stylers: { visibility: 'off' } },
                            { featureType: 'arterial', elementType: 'geometry', stylers: { color: '#fefefe' } },
                            { featureType: 'arterial', elementType: 'geometry.fill', stylers: { color: '#fefefe' } },
                            { featureType: 'poi', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'green', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'subway', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'manmade', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'local', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'arterial', elementType: 'labels', stylers: { visibility: 'off' } },
                            { featureType: 'boundary', elementType: 'all', stylers: { color: '#fefefe' } },
                            { featureType: 'building', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'label', elementType: 'labels.text.fill', stylers: { color: 'rgba(0,0,0,0)' } }
                        ]
                    }
                }
            };

            option && that.myChart.setOption(option);
            that.bmapParams.mapModel = that.myChart.getModel().getComponent('bmap').getBMap();
        },

        // #region  生成真实干扰源
        // 切换区域时，设置经纬度范围
        selectScene() {
            let that = this;
            // 区域1：经度-99.5～-95.5；纬度30～34
            // 区域2：经度-116～-112；纬度42～46
            // 区域3：经度-101～-97；纬度28～32
            // let minLon, maxLon, minLat, maxLat = 
            if (that.menu.selectSceneNum == 1) {
                that.menu.lonLatRangeStr = "-99.5,30;95.5,34"
                that.menu.minLon = -99.5
                that.menu.maxLon = -95.5
                that.menu.minLat = 30
                that.menu.maxLat = 34
            }
            else if (that.menu.selectSceneNum == 2) {
                that.menu.lonLatRangeStr = "-116,42;112,46"
                that.menu.minLon = -116
                that.menu.maxLon = -112
                that.menu.minLat = 42
                that.menu.maxLat = 46
            }
            else if (that.menu.selectSceneNum == 3) {
                that.menu.lonLatRangeStr = "-101,-97;28,32"
                that.menu.minLon = -101
                that.menu.maxLon = -97
                that.menu.minLat = 28
                that.menu.maxLat = 32

            }
        },

        // 切换干扰源生成方式
        changeInterferenceSrcType() {
            let that = this;
            that.clearMarkersByTag("location_real")
            if (that.menu.buildType == 0) {
                // todo 换接口
                getInterferenceDataList().then(response => {
                    const rdata = JSON.parse(JSON.stringify(response))
                    const code = rdata.code
                    const data = rdata.data
                    if (code == 200) {
                        that.menu.interferencePosReal = []
                        for (let i = 0; i < data.length; i++) {
                            const item = data[i]
                            that.menu.interferencePosReal.push({ latitude: item.lat, longitude: item.lon })

                            // 界面textarr中展示
                            let result = '经度:' + parseFloat(item.lon).toFixed(6) + ';纬度:' + parseFloat(item.lat).toFixed(6) + ';高度:0'
                            that.menu.interferencePosRealText += result + '\n'
                        }
                        that.menu.interferenceNum = data.length
                    }
                }).catch((r) => {
                    that.showNotification(r)
                });
            }
        },

        // 获取干扰源真实坐标
        async getInterferenceRealPos() {
            let that = this;
            if (!that.menu.selectSceneNum) {
                that.showNotification("请选择区域编号")
                return
            }

            if (!that.menu.interferenceRange || !that.menu.strartTime || !that.menu.endTime || !that.menu.interferenceNum) {
                that.showNotification("请检查输入")
                return
            }

            let receiveData = null
            // 自动
            if (that.menu.buildType == 0) {
                if (!that.menu.interferencePosReal) {
                    that.showNotification("未从库中获取到真实干扰源")
                    return
                }
                let locationRealStr = ''
                let points = []
                for (let index = 0; index < that.menu.interferencePosReal.length; index++) {
                    const element = that.menu.interferencePosReal[index];
                    points.push(new BMap.Point(element.longitude, element.latitude))
                    locationRealStr += element.longitude + ',' + element.latitude + ';'
                }
                if (locationRealStr.endsWith(';')) {
                    locationRealStr = locationRealStr.substring(0, locationRealStr.length - 1);
                }

                // 显示加载动画
                const loading = ElLoading.service({
                    lock: true,
                    text: '正在部署干扰源...',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                });

                await dataProcess2(that.menu.selectSceneNum, that.menu.strartTime, that.menu.endTime, that.menu.interferenceNum, locationRealStr, that.menu.interferenceRange).then(response => {
                    const rdata = JSON.parse(JSON.stringify(response))
                    const code = rdata.code
                    receiveData = JSON.parse(rdata.msg).location_real
                    if (code != 200) {
                        loading.close();
                        that.showNotification("获取干扰源错误")
                        return
                    }
                    loading.close();
                }).catch((r) => {
                    loading.close();
                    that.showNotification(r)
                });

                that.bmapParams.mapModel.setViewport(points);
            }
            // 手动
            else {
                // 显示加载动画
                const loading = ElLoading.service({
                    lock: true,
                    text: '正在部署干扰源...',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                });
                await dataProcess1(that.menu.interferenceNum, that.menu.interferenceRange, that.menu.selectSceneNum, that.menu.strartTime, that.menu.endTime).then(response => {
                    const rdata = JSON.parse(JSON.stringify(response))
                    const code = rdata.code
                    receiveData = JSON.parse(rdata.msg).location_real
                    if (code != 200) {
                        loading.close();
                        that.showNotification("获取干扰源错误")
                    }
                    loading.close();
                }).catch((r) => {
                    loading.close();
                    that.showNotification(r)
                });

                let points = []
                points.push(new BMap.Point(that.menu.minLon, that.menu.minLat))
                points.push(new BMap.Point(that.menu.maxLon, that.menu.maxLat))
                that.bmapParams.mapModel.setViewport(points);
            }

            that.menu.location_real = []
            that.clearMarkersByTag("location_real")
            for (let index = 0; index < receiveData.length; index++) {
                const element = receiveData[index];
                that.menu.location_real.push({ longitude: element.longitude, latitude: element.latitude })
                that.addMarker(new BMap.Point(element.longitude, element.latitude), "location_real", that.bmapParams.location_real, "真实位置")
            }
            that.playBeepSound()
        },
        //#endregion

        // #region 开始计算干扰程度检测和干扰定位
        async startCalculLocatAndDetect() {
            let that = this
            if (that.menu.location_real.length == 0) {
                that.showNotification("请先生成干扰源")
                return
            }
            if (!that.menu.gridSize) {
                that.showNotification("请输入网格长度")
                return
            }

            startCalculLocatAndDetectApi(that.menu, that.menu.taskName, that.menu.selectSceneNum, that.menu.gridSize, that.menu.timeStamp)
            that.showSuccess("任务执行成功！")

            // 等待 0.5 秒
            await new Promise(resolve => setTimeout(resolve, 500));
            // 打开任务列表
            that.historyMenuBool = true;
            that.getLatestData(5)
        },
        //#endregion

        //#region  历史数据
        // 展开/隐藏历史任务面单
        seeHistoryBtn() {
            let that = this
            if (!that.historyMenuBool) {
                that.getLatestData(5)
                that.historyMenuBool = true;
            }
            else {
                that.historyMenuBool = false;
            }
        },

        // 获取历史任务
        getLatestData(value) {
            let that = this;
            queryAdsbLastRecordList(value).then(response => {
                const rdata = JSON.parse(JSON.stringify(response))
                const code = rdata.code
                const data = rdata.data
                if (code == 200) {
                    that.historyInfo = []
                    // debugger
                    for (let i = 0; i < data.length; i++) {
                        const item = data[i]
                        that.historyInfo.push(
                            {
                                id: item.id,
                                createTime: that.formatDate(item.createTime),
                                name: item.name,
                                status: item.status,
                                paramsData: JSON.parse(item.paramsData),
                                result: JSON.parse(item.result),
                                areaNum: item.areaNum,
                                gridStep: item.gridStep
                            })
                    }
                }
            }).catch((r) => {
                that.showNotification(r)
            });
            that.showSuccess("调取历史任务")

        },

        seeOneHistoryInfo(row) {
            let that = this
            that.paramMenuBool = true
            // 更新面板
            that.menu = null
            that.menu = row.paramsData

            // 视图跳转
            let points = []
            points.push(new BMap.Point(that.menu.minLon, that.menu.minLat))
            points.push(new BMap.Point(that.menu.maxLon, that.menu.maxLat))
            that.bmapParams.mapModel.setViewport(points);

            // T
            console.log("tData:", row.result.T)
            that.menu.tData = row.result.T

            // 真实干扰展示
            that.menu.location_real = row.result.location_real
            that.clearMarkersByTag("location_real")
            for (let index = 0; index < that.menu.location_real.length; index++) {
                const element = that.menu.location_real[index];
                if (that.menu.tData == 0) {
                    that.addMarker(new BMap.Point(element.longitude, element.latitude), "location_real", that.bmapParams.location_real, "真实位置,误差为" + element.err)
                } else {
                    that.addMarker(new BMap.Point(element.longitude, element.latitude), "location_real", that.bmapParams.location_real, "真实位置")
                }
            }

            // 干扰检测展示
            console.log("row.result.interferenceMatrixData:", row.result.interferenceMatrixData)
            that.menu.interferenceMatrixData = that.normalizeData(row.result.interferenceMatrixData)
            that.setHeatmap(that.menu.minLon, that.menu.maxLon, that.menu.minLat, that.menu.maxLat, that.menu.gridSize, that.menu.interferenceMatrixData)

            // 模拟干扰源展示
            console.log("row.result.location_detect:", row.result.location_detect)
            that.menu.location_detect = row.result.location_detect
            that.clearMarkersByTag("location_detect_true")
            that.clearMarkersByTag("location_detect_virtual")
            for (let index = 0; index < that.menu.location_detect.length; index++) {
                const element = that.menu.location_detect[index];
                if (element.type == 1) {
                    that.addMarker(new BMap.Point(element.longitude, element.latitude), "location_detect_true", that.bmapParams.location_detect_true, "干扰源估计位置(实警)")
                }
                else if (element.type == -1) {
                    that.addMarker(new BMap.Point(element.longitude, element.latitude), "location_detect_virtual", that.bmapParams.location_detect_virtual, "干扰源估计位置(虚警)\n")
                }
            }

            // 平均误差
            console.log("row.result.LocationError_avg:", row.result.LocationError_avg)
            that.menu.LocationError_avg = row.result.LocationError_avg

            // point1
            console.log("row.result.point1:", row.result.point1)
            that.menu.point1 = row.result.point1
            that.clearMarkersByTag("point1")
            for (let index = 0; index < that.menu.point1.length; index++) {
                const element = that.menu.point1[index];
                points.push(new BMap.Point(element.longitude, element.latitude))
                that.addMarker(new BMap.Point(element.longitude, element.latitude), "point1", that.bmapParams.point1, "轨迹断裂点")
            }

            // point2
            console.log("row.result.point2:", row.result.point2)
            that.menu.point2 = row.result.point2
            that.clearMarkersByTag("point2")
            for (let index = 0; index < that.menu.point2.length; index++) {
                const element = that.menu.point2[index];
                points.push(new BMap.Point(element.longitude, element.latitude))
                that.addMarker(new BMap.Point(element.longitude, element.latitude), "point2", that.bmapParams.point2, "轨迹恢复点")
            }
        },
        //#endregion

        //#region  公共方法
        // 展示热力图
        setHeatmap(minLon, maxLon, minLat, maxLat, gridSize, data) {
            let that = this
            that.heatMap.lngExtent = [minLat, maxLat]
            that.heatMap.latExtent = [minLon, maxLon]
            that.heatMap.cellCount = [
                (that.heatMap.lngExtent[1] - that.heatMap.lngExtent[0]) / gridSize,
                (that.heatMap.latExtent[1] - that.heatMap.latExtent[0]) / gridSize]
            that.heatMap.cellSizeCoord = [gridSize, gridSize]

            var COLORS = ['#1482e5', '#70b4eb', '#b4e0f3', '#ffffff', '#00ff00', '#ff0000', '#FF9F3A', '#FF7290', '#C86DF0']
            echarts.use([
                TooltipComponent,
                VisualMapComponent,
                CustomChart,
                CanvasRenderer
            ]);

            var option;

            option = {
                backgroundColor: 'transparent',
                tooltip: {},
                visualMap: {
                    type: 'piecewise',
                    inverse: true,
                    top: 10,
                    right: 10,
                    pieces: [
                        { value: 0, label: '重度干扰', color: COLORS[0] },
                        { value: 1, label: '中度干扰', color: COLORS[1] },
                        { value: 2, label: '无干扰', color: COLORS[2] },
                        { value: 3, label: '无法判断', color: COLORS[3] },
                        { value: 4, label: '虚警', color: COLORS[4] },
                        { value: 5, label: '实警', color: COLORS[5] },
                        { value: 6, label: '真实位置', color: COLORS[6] },
                        { value: 7, label: '轨迹断裂点', color: COLORS[7] },
                        { value: 8, label: '轨迹恢复点', color: COLORS[8] },
                    ],
                    borderColor: '#ccc',
                    borderWidth: 2,
                    backgroundColor: '#eee',
                    dimension: 2,
                    inRange: {
                        color: COLORS,
                        opacity: 0.4
                    }
                },
                series: [
                    {
                        type: 'custom',
                        coordinateSystem: 'bmap',
                        renderItem: that.renderItem,
                        animation: false,
                        emphasis: {
                            itemStyle: {
                                color: 'yellow'
                            }
                        },
                        encode: {
                            tooltip: 2
                        },
                        data: data
                    }
                ],
                bmap: {
                    center: [0.5 * (minLon + maxLon), 0.5 * (minLat + maxLat)],
                    zoom: 8,
                    roam: true,
                    mapStyle: {
                        styleJson: [
                            { featureType: 'water', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'land', elementType: 'all', stylers: { color: '#f3f3f3' } },
                            { featureType: 'railway', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'highway', elementType: 'all', stylers: { color: '#999999' } },
                            { featureType: 'highway', elementType: 'labels', stylers: { visibility: 'off' } },
                            { featureType: 'arterial', elementType: 'geometry', stylers: { color: '#fefefe' } },
                            { featureType: 'arterial', elementType: 'geometry.fill', stylers: { color: '#fefefe' } },
                            { featureType: 'poi', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'green', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'subway', elementType: 'all', stylers: { visibility: 'off' } },
                            { featureType: 'manmade', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'local', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'arterial', elementType: 'labels', stylers: { visibility: 'off' } },
                            { featureType: 'boundary', elementType: 'all', stylers: { color: '#fefefe' } },
                            { featureType: 'building', elementType: 'all', stylers: { color: '#d1d1d1' } },
                            { featureType: 'label', elementType: 'labels.text.fill', stylers: { color: 'rgba(0,0,0,0)' } }
                        ]
                    }
                }
            };

            option && that.myChart.setOption(option);
        },

        // 播放声音
        playBeepSound() {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();

            const playSingleBeep = (delay) => {
                const oscillator = audioContext.createOscillator();
                const gainNode = audioContext.createGain();

                // 设置频率为 440Hz
                oscillator.frequency.setValueAtTime(440, audioContext.currentTime);

                // 连接振荡器到增益节点，再连接到音频上下文的输出
                oscillator.connect(gainNode);
                gainNode.connect(audioContext.destination);

                // 设置音量和播放时间
                gainNode.gain.setValueAtTime(0.5, audioContext.currentTime + delay);
                oscillator.start(audioContext.currentTime + delay); // 延迟播放
                oscillator.stop(audioContext.currentTime + delay + 0.2); // 0.2秒后停止
            };

            // 播放三次“滴滴滴”
            playSingleBeep(0);     // 立即播放
            setTimeout(() => playSingleBeep(0), 500);
            setTimeout(() => playSingleBeep(0), 900);
        },
        // 格式化时间
        formatDate(createTime) {
            const date = new Date(createTime);
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hours = String(date.getHours()).padStart(2, '0');
            const minutes = String(date.getMinutes()).padStart(2, '0');
            const seconds = String(date.getSeconds()).padStart(2, '0');
            return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
        },

        renderItem(params, api) {
            let that = this
            var context = params.context;
            var lngIndex = api.value(0);
            var latIndex = api.value(1);
            var coordLeftTop = [
                +(that.heatMap.latExtent[0] + lngIndex * that.heatMap.cellSizeCoord[0]).toFixed(6),
                +(that.heatMap.lngExtent[0] + latIndex * that.heatMap.cellSizeCoord[1]).toFixed(6)
            ];
            var pointLeftTop = that.getCoord(params, api, lngIndex, latIndex);
            var pointRightBottom = that.getCoord(params, api, lngIndex + 1, latIndex + 1);
            return {
                type: 'rect',
                shape: {
                    x: pointLeftTop[0],
                    y: pointLeftTop[1],
                    width: pointRightBottom[0] - pointLeftTop[0],
                    height: pointRightBottom[1] - pointLeftTop[1]
                },
                style: api.style({
                    stroke: 'rgba(0,0,0,0.1)'
                }),
                styleEmphasis: api.styleEmphasis()
            };
        },

        getCoord(params, api, lngIndex, latIndex) {
            let that = this
            var coords = params.context.coords || (params.context.coords = []);
            var key = lngIndex + '-' + latIndex;
            return (
                coords[key] ||
                (coords[key] = api.coord([
                    +(that.heatMap.latExtent[0] + lngIndex * that.heatMap.cellSizeCoord[0]).toFixed(6),
                    +(that.heatMap.lngExtent[0] + latIndex * that.heatMap.cellSizeCoord[1]).toFixed(6)
                ]))
            );
        },

        // 归一化数据
        normalizeData(data) {
            return data.map(([row, col, value]) => {
                let normalizedValue;
                if (value >= 0.9 && value <= 1) {
                    normalizedValue = 0;
                } else if (value >= 0.5 && value < 0.9) {
                    normalizedValue = 1;
                } else if (value >= 0 && value < 0.5) {
                    normalizedValue = 2;
                } else if (value === -1) {
                    normalizedValue = 3;
                }
                return [row, col, normalizedValue];
            });
        },

        // 警告信息
        showNotification(message) {
            this.$notify({
                title: '警告',
                message: message,
                type: 'warning',
                duration: 0  // duration 为 0 表示不会自动关闭
            });
        },
        // 成功信息
        showSuccess(message) {
            // 替换 message 中的 \n 为 <br> 元素
            message = message.replace(/\n/g, '<br />');

            this.$notify({
                title: '成功',
                message: `<div style="white-space: pre-line;">${message}</div>`,
                type: 'success',
                dangerouslyUseHTMLString: true,
                duration: 2000  // duration 为 0 表示不会自动关闭
            });
        },

        // 添加标记
        addMarker(pos, tag, colour, label) {
            let that = this;
            var icon = null;
            if (colour == "green") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(0, -22) });
            }
            else if (colour == "blue") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(-18, -22) });
            }
            else if (colour == "red") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(-36, -22) });
            }
            else if (colour == "yellow") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(-54, -22) });
            }
            else if (colour == "purple") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(-72, -22) });
            }
            else if (colour == "pink") {
                icon = new BMap.Icon('/allStyleMarker.png', new BMap.Size(18, 26), { "imageOffset": new BMap.Size(-90, -22) });
            }
            var marker = new BMap.Marker(pos, { icon: icon });
            marker.tag = tag;
            marker.setTop(true);
            // 添加标签
            var label = new BMap.Label(label, { position: pos, offset: new BMap.Size(-20, -25) });
            label.setStyle({
                color: "black",
                fontSize: "12px",
                backgroundColor: "white",
                border: "1px solid black",
                borderRadius: "3px",
                padding: "2px"
            });
            // Show label on mouseover
            marker.addEventListener("mouseover", function () {
                label.setStyle({ display: "block" });
            });

            // Hide label on mouseout
            marker.addEventListener("mouseout", function () {
                label.setStyle({ display: "none" });
            });
            marker.setLabel(label);

            that.bmapParams.mapModel.addOverlay(marker);
            that.bmapParams.markers.push(marker);
        },

        // 根据tag清除插入的位置标记
        clearMarkersByTag(tag) {
            let that = this
            that.bmapParams.markers = that.bmapParams.markers.filter(marker => {
                if (marker.tag === tag) {
                    that.bmapParams.mapModel.removeOverlay(marker);
                    return false;
                }
                return true;
            });
        },

        // 展开/隐藏参数设置面单
        setParadata() {
            let that = this
            if (!that.paramMenuBool) {
                that.paramMenuBool = true;
            }
            else {
                that.paramMenuBool = false;
            }
        },
        //#endregion
    },
};
</script>

<style scoped>
#main {
    width: 100%;
    height: 500px;
}

.setParadata {
    border-radius: 5px;
    height: 32px;
    width: 100px;
    position: absolute;
    left: 20px;
    top: 10px;
    color: #ffffff;
    background: rgb(0, 145, 255);
    border: 1px solid #ffffff;
    background-size: cover;
    z-index: 6;
}

.setParadata:hover {
    color: #fff;
    fill: #fff;
    background: rgba(0, 145, 255, 0.619);
    background-size: cover;
    border-color: rgb(170, 242, 255);
    box-shadow: 0 0 8px #fff;
}

.seeHistoryBtn {
    border-radius: 5px;
    height: 32px;
    width: 100px;
    position: absolute;
    left: 110px;
    top: 10px;
    color: #ffffff;
    background: rgb(0, 145, 255);
    border: 1px solid #ffffff;
    background-size: cover;
    z-index: 6;
}

.seeHistoryBtn:hover {
    color: #fff;
    fill: #fff;
    background: rgba(0, 145, 255, 0.619);
    background-size: cover;
    border-color: #aef;
    box-shadow: 0 0 8px #fff;
}

.menu {
    border-radius: 5px;
    height: auto;
    width: 310px;
    position: absolute;
    left: 20px;
    top: 50px;
    color: #2b0700;
    background: #ffffff;
    border: 1px solid #303336;
    background-size: cover;
    z-index: 6;
    padding: 5px;
}

.history-menu {
    border-radius: 5px;
    width: 62%;
    height: 30%;
    position: absolute;
    top: 69%;
    left: 25%;
    border: 1px solid #303336;
    background-color: #ffffff;
    z-index: 6;
}

.history-table {
    height: 80%;
    width: 100%;
    overflow: auto;
}

.history-table .el-table__header th {
    font-size: 18px;
    font-weight: bold;
}
</style>